home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / artemis1 / src / dispman.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-11  |  30.5 KB  |  1,159 lines

  1. /*
  2.     ARTemis (Graphic Editor for FM-TOWNS)  (c) MATSUUCHI Ryosuke 1992,1993
  3.  
  4.     dispman.c    Display Manager(表示管理部; 略称DM)
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <msdos.cf>
  9. #include <malloc.h>
  10. #include "ge.h"
  11. #include "imageman.h"
  12. #include "arealist.h"
  13.  
  14. static    int            menuplt[16];
  15. static    Arealist    *menu1box;
  16. static    Arealist    *menu2box;
  17. #define    HIGH16LOW32K    0
  18. #define    HIGH32K            1
  19. static    int        scrtype;             // HIGH16LOW32K / HIGH32K
  20. static    int        zoomrate;
  21. static    int        dispx,dispy;
  22. static    int        _dispxlen,_dispylen;    // 表示されている範囲
  23. static    int        vx,vy;                // VRAM 上に存在するimageの全体でのoffset
  24. static    bool    _lat1disp,_lat2disp;
  25. static    int        lat2xstep,lat2ystep;
  26. static    int        lat2xofs=0,lat2yofs=0;
  27. static    bool    maskdisp = NO;
  28.  
  29. typedef struct {
  30.     int x,y,xlen,ylen;    // その時点の zoomrate での範囲
  31.     char *gbuf1;        // imagebuf の画像の保存用
  32.     char *gbuf2;        // menu2 レイヤの画像の保存用(スクロール時)
  33. } Menu2box;
  34.  
  35. /*
  36. ★関数一覧
  37.  
  38.     DMnew                        DM の初期化
  39.     DMdelete                    DM の終了
  40.     
  41.     DMgetifonepage                レイヤ構成が1ページ上かどうかを得る
  42.     DMgetxsize                    menu1レイヤの横幅
  43.     DMgetysize                    menu1レイヤの縦幅
  44.     DMgetmenuplt                menu1レイヤにおけるパレット設定を得る
  45.     DMdispcsr                    menu1レイヤに重ねてカーソルを表示
  46.     DMerasecsr                    menu1レイヤ上のカーソルを消去
  47.     DMchangecsrtype                カーソルの種別の変更
  48.  
  49.     DMmenu1_addbox                menu1レイヤに新たに矩形領域を設定する
  50.     DMmenu1_deletebox            menu1レイヤの矩形領域を削除する
  51.     DMmenu2_addbox                menu2レイヤに新たに矩形領域を設定する
  52.     DMmenu2_deletebox            menu2レイヤの矩形領域を削除する
  53.  
  54.     DMimage_setdispxy            編集画像のどこをimageレイヤに表示するか
  55.     DMimage_limitdispxy            ある座標の組を、dispx,dispy の設定限界内に制限
  56.                                 する
  57.     DMimage_refresh                imageレイヤの内容を(編集画像に従って)更新する
  58.     DMimage_setzoomrate            imageレイヤの拡大率はなん倍か
  59.     DMimage_getzoomrate            現在設定されている拡大率を得る
  60.     DMimage_setlatticeswitch    imageレイヤに重ねる格子を表示する・しない
  61.     DMimage_setmaskdisp            マスク部分を反転表示する・しない
  62.     DMimage_getxbytes            imageレイヤの1ラインのバイト数を得る
  63.     DMimage_pset                imageレイヤに点を打つ
  64.     DMimage_line                imageレイヤに直線を描く
  65.     DMimage_hline                imageレイヤに水平直線を描く
  66.     DMimage_vline                imageレイヤに垂直直線を描く
  67.     DMimage_boxline                imageレイヤに矩形(枠)を描く
  68.     DMimage_boxfill                imageレイヤに矩形フィルする
  69. */
  70.  
  71. /*--------------------------------------------------------*/
  72. /*                 領域分割の補助ルーチン                 */
  73. /*--------------------------------------------------------*/
  74.  
  75. #define    INTMIN    (-100000)
  76. #define    INTMAX    ( 100000)
  77.  
  78. static int andarea(Area *a1, Area *a2, Area *outarea)
  79. // Area a1,a2 の積の領域を outarea に代入
  80. // 返値: 積がφでなければ 1, φなら 0
  81. {
  82.     outarea->x1 = _max(a1->x1, a2->x1);
  83.     outarea->y1 = _max(a1->y1, a2->y1);
  84.     outarea->x2 = _min(a1->x2, a2->x2);
  85.     outarea->y2 = _min(a1->y2, a2->y2);
  86.     if (outarea->x1 <= outarea->x2 && outarea->y1 <= outarea->y2)
  87.         return 1;
  88.     else
  89.         return 0;
  90. }
  91.  
  92. static void splitarea(Area *obj, Area *sbj, Arealist *outal)
  93. // obj を sbj で 0~4個の Area に分割し、それを outal に追加
  94. {
  95.     Area a,a2;
  96.     // sbj の上の領域
  97.     a.x1=INTMIN, a.y1=INTMIN, a.x2=INTMAX, a.y2=sbj->y1-1;
  98.     if (andarea(&a, obj, &a2))
  99.         ALaddarea(outal, &a2);
  100.     // sbj の左の領域
  101.     a.x1=INTMIN, a.y1=sbj->y1, a.x2=sbj->x1-1, a.y2=sbj->y2;
  102.     if (andarea(&a, obj, &a2))
  103.         ALaddarea(outal, &a2);
  104.     // sbj の右の領域
  105.     a.x1=sbj->x2+1, a.y1=sbj->y1, a.x2=INTMAX, a.y2=sbj->y2;
  106.     if (andarea(&a, obj, &a2))
  107.         ALaddarea(outal, &a2);
  108.     // sbj の下の領域
  109.     a.x1=INTMIN, a.y1=sbj->y2+1, a.x2=INTMAX, a.y2=INTMAX;
  110.     if (andarea(&a, obj, &a2))
  111.         ALaddarea(outal, &a2);
  112. }
  113.  
  114. static Arealist *makearealist()    // menu1box に従い、画面を分割する
  115. {
  116.     Arealist *al;
  117.     Area a,*q;
  118.     if ((al = ALnew()) == NULL)
  119.         return NULL;
  120.     a.x1=a.y1=0, a.x2=(scrtype==HIGH32K?511:639), a.y2=479;
  121.     ALaddarea(al,&a);
  122.     for (q=ALgetfirstarea(menu1box); q!=NULL; q=ALgetnextarea(menu1box))
  123.     {
  124.         Arealist *al2; Area *p;
  125.         if ((al2 = ALnew()) == NULL)
  126.             return NULL;
  127.         for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
  128.             splitarea(p, q, al2);
  129.         ALdelete(al);
  130.         al = al2;
  131.     }
  132.     return al;
  133. }
  134.  
  135. /*--------------------------------------------------------*/
  136. /*                 格子表示の補助ルーチン                 */
  137. /*--------------------------------------------------------*/
  138.  
  139. static void _drawlattice(Area *area, bool lat1, int col1, bool lat2, int col2)
  140. {
  141.     int t,x,xi,y,yi;
  142.     if (zoomrate==1)
  143.         return;
  144.     if (zoomrate == 2)
  145.         lat1 = NO;
  146.     // 小格子の表示
  147.     if (lat1)
  148.     {
  149.         for (t=area->x1+zoomrate-1, x=t-t%zoomrate+zoomrate-1, xi=t/zoomrate;
  150.              x <= area->x2;  x+=zoomrate, xi++)
  151.             gvline(x,area->y1,area->y2,col1, DrawNORMAL);
  152.         for (t=area->y1+zoomrate-1, y=t-t%zoomrate+zoomrate-1, yi=t/zoomrate;
  153.              y <= area->y2;  y+=zoomrate, yi++)
  154.             ghline(area->x1,area->x2,y,col1,DrawNORMAL);
  155.     }
  156.     // 大格子の表示
  157.     if (lat2)
  158.     {
  159.         for (t=area->x1+zoomrate-1, x=t-t%zoomrate+zoomrate-1, xi=t/zoomrate;
  160.              x <= area->x2;  x+=zoomrate, xi++)
  161.         {
  162.             if (((dispx+xi)-lat2xofs+1)%lat2xstep==0)
  163.                 gvline(x,area->y1,area->y2,col2, DrawNORMAL);
  164.         }
  165.         for (t=area->y1+zoomrate-1, y=t-t%zoomrate+zoomrate-1, yi=t/zoomrate;
  166.              y <= area->y2;  y+=zoomrate, yi++)
  167.         {
  168.             if (((dispy+yi)-lat2yofs+1)%lat2ystep==0)
  169.                 ghline(area->x1,area->x2,y,col2,DrawNORMAL);
  170.         }
  171.     }
  172. }
  173.  
  174. static void dispalllattice()
  175. {
  176.     Arealist *al; Area *p;
  177.     if ((al = makearealist()) == NULL)
  178.         return;
  179.     for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
  180.         _drawlattice(p,_lat1disp,menuplt[Black],_lat2disp,menuplt[LatticeColor]);
  181.     ALdelete(al);
  182. }
  183.  
  184. static void erasealllattice()
  185. {
  186.     Arealist *al; Area *p;
  187.     if (zoomrate == 1 || scrtype == HIGH32K || (al = makearealist()) == NULL)
  188.         return;
  189.     for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
  190.     {
  191.         gboxfill(p->x1,p->y1,p->x2,p->y2,0,DrawNORMAL);
  192.         // _drawlattice(p,_lat1disp,0,_lat2disp,0);
  193.     }
  194.     ALdelete(al);
  195. }
  196.  
  197. static void displattice2()
  198. {
  199.     if (!_lat2disp)
  200.         return;
  201.     Arealist *al; Area *p;
  202.     if ((al = makearealist()) == NULL)
  203.         return;
  204.     for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
  205.         _drawlattice(p,NO,0,YES,menuplt[LatticeColor]);
  206.     ALdelete(al);
  207. }
  208.  
  209. static void eraselattice2()
  210. {
  211.     Arealist *al; Area *p;
  212.     if ((al = makearealist()) == NULL)
  213.         return;
  214.     for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
  215.         _drawlattice(p,NO,0,YES,((_lat1disp && zoomrate > 2) ? menuplt[Black] : 0));
  216.     ALdelete(al);
  217. }
  218.  
  219. /*--------------------------------------------------------*/
  220. /*              画面モード設定の補助ルーチン              */
  221. /*--------------------------------------------------------*/
  222.  
  223. static void setscreen()
  224. // scrtype に従って画面モードを設定、パレットの初期化も行う
  225. {
  226.     if (scrtype == HIGH16LOW32K)
  227.     {
  228.         gwrtpage(0);
  229.         gscreen(3);
  230.         gwrtpage(1);
  231.         gscreen(10);
  232.         gdsploc(0,0);
  233.         gscrzoom(zoomrate,zoomrate);
  234.         gdsparea(640/zoomrate,480/zoomrate);
  235.         gwrtpage(0);
  236.         // パレット設定    
  237.         grp_setplt(0,                0x000000);
  238.         grp_setplt(Black,            0x000000);
  239.         grp_setplt(Gray1,            0x202020);
  240.         grp_setplt(Gray2,            0x303030);
  241.         grp_setplt(Gray3,            0x505050);
  242.         grp_setplt(Gray4,            0x707070);
  243.         grp_setplt(Gray5,            0x808080);
  244.         grp_setplt(Gray6,            0xa0a0a0);
  245.         grp_setplt(Gray7,            0xc0c0c0);
  246.         grp_setplt(Gray8,            0xd0d0d0);
  247.         grp_setplt(White,            0xf0f0f0);
  248.         grp_setplt(Yellow,            0xf0f000);
  249.         grp_setplt(COL_menuShade,    0x404050);
  250.         grp_setplt(COL_menu,        0x9090b0);
  251.         grp_setplt(COL_menuLight,    0xe0e0f0);
  252.         grp_setplt(COL_menu2,        0xb0b0c0);
  253.     }
  254.     else if (scrtype == HIGH32K)
  255.     {
  256.         gwrtpage(0);
  257.         gscreen(17);
  258.         gdsploc(0,0);
  259.         gscrzoom(1,1);
  260.         gdsparea(512,480);
  261.         grboxfill(0,0,512,480,0,DrawNORMAL);
  262.     }
  263. }
  264.  
  265. /*--------------------------------------------------------*/
  266. /*                     menuplt の設定                     */
  267. /*--------------------------------------------------------*/
  268.  
  269. static void setmenuplt()
  270. {
  271.     int i;
  272.     if (scrtype == HIGH16LOW32K)
  273.     {
  274.         for (i=0; i<16; i++)
  275.             menuplt[i] = i;
  276.     }
  277.     else if (scrtype == HIGH32K)
  278.     {
  279.         for (i=0; i<16; i++)
  280.         {
  281.             switch (i)
  282.             {
  283.             case White:                menuplt[i] = 32767;                    break;
  284.             case Black:                menuplt[i] = 0;                        break;
  285.             #define G(n) ((n)*1024+(n)*32+(n))
  286.             case Gray1:                menuplt[i] = G(3);                    break;
  287.             case Gray2:                menuplt[i] = G(7);                    break;
  288.             case Gray3:                menuplt[i] = G(10);                    break;
  289.             case Gray4:                menuplt[i] = G(14);                    break;
  290.             case Gray5:                menuplt[i] = G(17);                    break;
  291.             case Gray6:                menuplt[i] = G(21);                    break;
  292.             case Gray7:                menuplt[i] = G(24);                    break;
  293.             case Gray8:                menuplt[i] = G(28);                    break;
  294.             #undef G
  295.             case Transparent:        menuplt[i] = 0x8000;                break;
  296.             case Yellow:            menuplt[i] = 31*1024+31*32+ 0;        break;
  297.             case COL_menu:            menuplt[i] = 19*1024+19*32+22;        break;
  298.             case COL_menuLight:        menuplt[i] = 28*1024+28*32+31;        break;
  299.             case COL_menuShade:        menuplt[i] = 8*1024+8*32+10;        break;
  300.             case COL_menu2:            menuplt[i] = 22*1024+22*32+24;        break;
  301.             default:                menuplt[i] = 31;                    break;
  302.             }
  303.         }
  304.     }
  305. }
  306.  
  307. /*--------------------------------------------------------*/
  308. /*             Display Manager の初期化/終了             */
  309. /*--------------------------------------------------------*/
  310.  
  311. int    DMnew(int reso)            // DM の初期化
  312. // reso: 0 = 画面を16色高解像度ページ+32K色低解像度ページの構成で初期化
  313. //         1 = 画面を32K色高解像度ページのみの構成で初期化
  314. // 返値 0=成功
  315. {
  316.     int i;
  317.     if ((menu1box = ALnew()) == NULL)
  318.         return -1;
  319.     if ((menu2box = ALnew()) == NULL)
  320.         return -1;
  321.     scrtype = (reso==0 ? HIGH16LOW32K : HIGH32K);
  322.     dispx = dispy = 0;
  323.     vx = vy = 0;
  324.     _lat1disp = _lat2disp = NO;
  325.     lat2xstep = lat2ystep = 16;
  326.     lat2xofs = lat2yofs = 0;
  327.     if (scrtype == HIGH16LOW32K)
  328.         zoomrate=2, _dispxlen=640/zoomrate, _dispylen=480/zoomrate;
  329.     else if (scrtype == HIGH32K)
  330.         zoomrate=1, _dispxlen=512, _dispylen=480;
  331.     setmenuplt();
  332.     // 画面モードの設定
  333.     ginit();
  334.     EGB_work = _egbwork;
  335.     setscreen();
  336. }
  337.  
  338. void DMdelete(void)            // DM の終了
  339. {
  340.     if (scrtype == HIGH16LOW32K)
  341.     {
  342.         gwrtpage(0);
  343.         grboxfill(0,0,640,480,0,DrawNORMAL);
  344.         gwrtpage(1);
  345.         grboxfill(0,0,512,256,0,DrawNORMAL);
  346.         gwrtpage(0);
  347.     }
  348.     else
  349.     {
  350.         gwrtpage(0);
  351.         grboxfill(0,0,512,480,0,DrawNORMAL);
  352.     }
  353. }
  354.  
  355. /*--------------------------------------------------------*/
  356. /*         Display Manager の各種パラメータの取得         */
  357. /*--------------------------------------------------------*/
  358.  
  359. int DMgetifonepage(void)    // レイヤ構成が1ページ上かどうかを得る
  360. // 返値: 0=1ページ上ではない  1=1ページ上
  361. {
  362.     return (scrtype == HIGH16LOW32K ? 0 : 1);
  363. }
  364.  
  365. int DMgetxsize(void)        // menu1レイヤの横幅を得る
  366. {
  367.     return (scrtype == HIGH32K ? 512 : 640);
  368. }
  369.  
  370. int DMgetysize(void)        // menu1レイヤの縦幅を得る
  371. {
  372.     return 480;
  373. }
  374.  
  375. void DMimage_getdispxy(int *x,int *y)
  376. {
  377.     *x = dispx;
  378.     *y = dispy;
  379. }
  380.  
  381. void DMimage_getdispxylen(int *xlen, int *ylen)
  382. {
  383.     *xlen = _dispxlen;
  384.     *ylen = _dispylen;
  385. }
  386.  
  387. int DMgetpage1x(int x)
  388. {
  389.     if (scrtype == HIGH16LOW32K)
  390.         return (dispx-vx)+x/zoomrate;
  391.     else if (scrtype == HIGH32K)
  392.         return x;
  393. }
  394.  
  395. int DMgetpage1y(int y)
  396. {
  397.     if (scrtype == HIGH16LOW32K)
  398.         return (dispy-vy)+y/zoomrate;
  399.     else if (scrtype == HIGH32K)
  400.         return y;
  401. }
  402.  
  403. void DMimage_getvramxy(int *x, int *y)
  404. {
  405.     *x = vx;
  406.     *y = vy;
  407. }
  408.  
  409. int DMgetmenuplt(int n)        // menu1レイヤにおけるパレット設定を得る
  410. {
  411.     return menuplt[n];
  412. }
  413.  
  414. int DMimage_getzoomrate()
  415. {
  416.     return zoomrate;
  417. }
  418.  
  419. int DMimage_getxbytes()
  420. {
  421.     return 1024;
  422. }
  423.  
  424.  
  425. static bool csrdisp = NO;
  426. static int  csrx,csry;
  427.  
  428. void DMerasecsr(void)        // menu1レイヤ上のカーソルを消去
  429. {
  430.     if (!csrdisp)
  431.         return;
  432.     csrdisp = NO;
  433.     int col;
  434.     col = (DMgetifonepage() ? White : csrcol);
  435.     ghline(0,DMgetxsize()-1,csry,DMgetmenuplt(col),DrawXOR);
  436.     gvline(csrx,0,DMgetysize()-1,DMgetmenuplt(col),DrawXOR);
  437. }
  438.  
  439. void DMdispcsr(int x,int y)    // menu1レイヤに重ねてカーソルを表示
  440. {
  441.     if (csrdisp)
  442.         DMerasecsr();
  443.     if (0 <= x && x < DMgetxsize() && 0<=y && y<DMgetysize())
  444.     {
  445.         csrdisp = YES;
  446.         csrx = x;
  447.         csry = y;
  448.         int col;
  449.         col = (DMgetifonepage() ? White : csrcol);
  450.         ghline(0,DMgetxsize()-1,y,DMgetmenuplt(col),DrawXOR);
  451.         gvline(x,0,DMgetysize()-1,DMgetmenuplt(col),DrawXOR);
  452.     }
  453. }
  454.  
  455.  
  456. void DMchangecsrtype(int type)    // カーソルの種別の変更
  457. {
  458. }
  459.  
  460. /*--------------------------------------------------------*/
  461. /*       menu1, menu2 レイヤに領域を追加/削除する        */
  462. /*--------------------------------------------------------*/
  463.  
  464. int DMmenu1_addbox(int x,int y,int xlen,int ylen)
  465. // menu1レイヤに新たに矩形領域を設定する
  466. {
  467.     Area a,*ap;  bool sw2nd;
  468.     a.x1=x, a.y1=y, a.x2=x+xlen-1, a.y2=y+ylen-1;
  469.     sw2nd = (ALgetfirstarea(menu1box) == NULL ? NO : YES);    // 2番目以降?
  470.     if ((ap = ALaddarea(menu1box, &a)) == NULL)
  471.         return -1;
  472.     int bufsize;  char *gbuf;
  473.     if (scrtype == HIGH16LOW32K)
  474.         bufsize = (((xlen+7)/8)*8)*ylen/2;
  475.     else if (scrtype == HIGH32K)
  476.         bufsize = xlen*ylen*2;
  477.     if (sw2nd)
  478.     {
  479.         if ((gbuf = malloc(bufsize)) == NULL) {
  480.             ALdeletearea(menu1box);
  481.             return -1;
  482.         }
  483.         ALarea_setdata(ap,gbuf);
  484.         gwrtpage(0);
  485.         grgetblk(gbuf,x,y,xlen,ylen);
  486.     }
  487.     else
  488.         ALarea_setdata(ap,NULL);
  489.     return 0;
  490. }
  491.  
  492. int DMmenu1_deletebox(void)    // menu1レイヤの矩形領域を削除する
  493. // (最後に設定した領域を削除する)
  494. {
  495.     Area *ap;  char *gbuf;
  496.     if ((ap = ALgetfirstarea(menu1box)) != NULL)
  497.     {
  498.         if ((gbuf = ALarea_getdata(ap)) != NULL)
  499.         {
  500.             grputblk(ap->x1, ap->y1, ap->x2-ap->x1+1, ap->y2-ap->y1+1,
  501.                      gbuf,DrawNORMAL);
  502.             free(gbuf);
  503.         }
  504.         else
  505.             gboxfill(ap->x1,ap->y1,ap->x2,ap->y2,0,DrawNORMAL);
  506.         ALdeletearea(menu1box);
  507.     }
  508.     if (scrtype == HIGH32K)
  509.         DMimage_refresh();
  510.     erasealllattice();
  511.     dispalllattice();
  512.     return 0;
  513. }
  514.  
  515. int DMmenu2_addbox(int x,int y,int xlen,int ylen)
  516. // menu2レイヤに新たに矩形領域を設定する
  517. {
  518.     Area a,*ap;
  519.     a.x1=x, a.y1=y, a.x2=x+xlen-1, a.y2=y+ylen-1;
  520.     if ((ap=ALaddarea(menu2box, &a)) == NULL)
  521.         return -1;
  522.     if (scrtype == HIGH16LOW32K)
  523.     {
  524.         Menu2box b,*bp;
  525.         b.x = x / zoomrate;
  526.         b.y = y / zoomrate;
  527.         b.xlen = (xlen+zoomrate-1) / zoomrate;
  528.         b.ylen = (ylen+zoomrate-1) / zoomrate;
  529.         if ((bp = (Menu2box*)malloc(sizeof(Menu2box)+b.xlen*b.ylen*4)) == NULL)
  530.         {
  531.             ALdeletearea(menu2box);
  532.             return -1;
  533.         }
  534.         *bp = b;
  535.         bp->gbuf1 = (char*)bp + sizeof(Menu2box);
  536.         bp->gbuf2 = (char*)bp + sizeof(Menu2box) + b.xlen*b.ylen*2;
  537.         gwrtpage(1);
  538.         grgetblk(bp->gbuf1,dispx-vx+b.x,dispy-vy+b.y,b.xlen,b.ylen);
  539.         gwrtpage(0);
  540.         ALarea_setdata(ap,bp);
  541.     }
  542.     return 0;
  543. }
  544.  
  545. int DMmenu2_deletebox(void)    // menu2レイヤの矩形領域を削除する
  546. {
  547.     if (scrtype == HIGH16LOW32K)
  548.     {
  549.         Area *ap;
  550.         if ((ap = ALgetfirstarea(menu2box)) != NULL)
  551.         {
  552.             Menu2box *bp;
  553.             bp = (Menu2box *)ALarea_getdata(ap);
  554.             gwrtpage(1);
  555.             grputblk(dispx-vx+bp->x,dispy-vy+bp->y,
  556.                      bp->xlen,bp->ylen,bp->gbuf1, DrawNORMAL);
  557.             gwrtpage(0);
  558.             free(bp);
  559.         }
  560.     }
  561.     ALdeletearea(menu2box);
  562.     return 0;
  563. }
  564.  
  565.  
  566. /*--------------------------------------------------------*/
  567. /*              image レイヤの表示位置の変更              */
  568. /*--------------------------------------------------------*/
  569.  
  570. void DMimage_limitdispxy(int x, int y, int *newx, int *newy)
  571. {
  572.     *newx = x, *newy = y;
  573.     if (x < 0)
  574.         *newx = 0;
  575.     else if (x + _dispxlen > EIMgetxsize())
  576.         *newx = EIMgetxsize() - _dispxlen;
  577.     if (y < 0)
  578.         *newy = 0;
  579.     else if (y + _dispylen > EIMgetysize())
  580.         *newy = EIMgetysize() - _dispylen;
  581. }
  582.  
  583. int DMimage_setdispxy(int x,int y)    // 編集画像のどこをimageレイヤに表示するか
  584. // 結果的に x,y がどうなったかも返すべき?
  585. {
  586.     Area *ap;
  587.     if (x < 0)
  588.         x = 0;
  589.     else if (x+_dispxlen > EIMgetxsize())
  590.         x = EIMgetxsize() - _dispxlen;
  591.     if (y < 0)
  592.         y = 0;
  593.     else if (y+_dispylen > EIMgetysize())
  594.         y = EIMgetysize() - _dispylen;
  595.     if (scrtype == HIGH16LOW32K)
  596.     {
  597.         /*
  598.             画面モード構成が16色高解像度+32K色低解像度の場合:
  599.         
  600.             新たに表示したい領域が、すでにVRAM上に存在する範囲ならば、
  601.             ハード的に表示範囲を変更するだけ。
  602.             ここで、「新たに表示したい領域」とは、編集画像上のある矩形領域
  603.             であり、その基準座標は(x,y)、大きさは
  604.             (DMgetxsize()/zoomrate, DMgetysize()/zoomrate) という領域である。
  605.         
  606.             この領域が、まだ VRAM上に存在しない領域を含んでいる場合、
  607.             編集画像バッファよりデータを転送する。
  608.             (x,y)-VRAM上に存在しない領域を表示したいという場合は、
  609.         */
  610.         eraselattice2();
  611.         // menu2box の内容を復帰
  612.         if ((ap = ALgetfirstarea(menu2box)) != NULL)
  613.         {
  614.             gwrtpage(1);
  615.             for ( ; ap!=NULL; ap=ALgetnextarea(menu2box))
  616.             {
  617.                 Menu2box *bp;
  618.                 bp = (Menu2box*)ALarea_getdata(ap);
  619.                 grgetblk(bp->gbuf2,
  620.                          dispx-vx+bp->x,dispy-vy+bp->y,bp->xlen,bp->ylen);
  621.                 grputblk(dispx-vx+bp->x,dispy-vy+bp->y,bp->xlen,bp->ylen,
  622.                          bp->gbuf1,DrawNORMAL);
  623.             }
  624.             gwrtpage(0);
  625.         }
  626.         bool vc = NO; // vx,vyを変更したかどうか
  627.         if (x < vx)
  628.             vx = _max(0, x+_dispxlen-512), vc=YES;
  629.         else if (vx+512 < x+_dispxlen)
  630.             vx = _min(EIMgetxsize()-512, x), vc=YES;
  631.         if (y < vy)
  632.             vy = _max(0, y+_dispylen-256), vc=YES;
  633.         else if (vy+256 < y+_dispylen)
  634.             vy = _min(EIMgetysize()-256, y), vc=YES;
  635.         if (vc)
  636.             xymemcpy(0x104,0x40000, getds(),(int)EIMadrs(vx,vy),
  637.                      512*2, 256, DMimage_getxbytes(), EIMgetxbytes());
  638.         dispx = x, dispy = y;
  639.         gwrtpage(1);
  640.         gdsploc(dispx-vx,dispy-vy);
  641.         gwrtpage(0);
  642.         // menu2box の内容を退避
  643.         if ((ap = ALgetfirstarea(menu2box)) != NULL)
  644.         {
  645.             gwrtpage(1);
  646.             for ( ; ap!=NULL; ap=ALgetnextarea(menu2box))
  647.             {
  648.                 Menu2box *bp;
  649.                 bp = (Menu2box*)ALarea_getdata(ap);
  650.                 grgetblk(bp->gbuf1,
  651.                          dispx-vx+bp->x,dispy-vy+bp->y,bp->xlen,bp->ylen);
  652.                 grputblk(dispx-vx+bp->x,dispy-vy+bp->y,bp->xlen,bp->ylen,
  653.                          bp->gbuf2,DrawNORMAL);
  654.             }
  655.             gwrtpage(0);
  656.         }
  657.         displattice2();
  658.     }
  659.     else if (scrtype == HIGH32K)
  660.     {
  661.         dispx = x, dispy = y;
  662.         if (zoomrate == 1)
  663.         {
  664.             Arealist *al; Area *p;
  665.             if ((al = makearealist()) != NULL)
  666.             {
  667.                 for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
  668.                     xymemcpy(0x10c,1024*p->y1+p->x1*2,
  669.                              getds(),(int)EIMadrs(dispx + p->x1,dispy + p->y1),
  670.                              (p->x2 - p->x1 + 1)*2,  p->y2 - p->y1 + 1,
  671.                              DMimage_getxbytes(), EIMgetxbytes());
  672.                 ALdelete(al);
  673.             }
  674.         }    
  675.     }
  676.     return 0;
  677. }
  678.  
  679. /*--------------------------------------------------------*/
  680. /*                image レイヤの内容の更新                */
  681. /*--------------------------------------------------------*/
  682.  
  683. int DMimage_refresh(void)    // imageレイヤの内容を(編集画像に従って)更新する
  684. {
  685.     if (scrtype == HIGH16LOW32K)
  686.     {
  687.         xymemcpy(0x104,0x40000, getds(),(int)EIMadrs(vx,vy),
  688.                  512*2, 256, DMimage_getxbytes(), EIMgetxbytes());
  689.     }
  690.     else if (scrtype == HIGH32K)
  691.     {
  692.         Arealist *al; Area *p;
  693.         if ((al = makearealist()) != NULL)
  694.         {
  695.             for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
  696.                 xymemcpy(0x10c,1024*p->y1+p->x1*2,
  697.                          getds(),(int)EIMadrs(dispx + p->x1,dispy + p->y1),
  698.                          (p->x2 - p->x1 + 1)*2,  p->y2 - p->y1 + 1,
  699.                          DMimage_getxbytes(), EIMgetxbytes());
  700.             ALdelete(al);
  701.         }
  702.     }
  703.     return 0;
  704. }
  705.  
  706. /*--------------------------------------------------------*/
  707. /*               image レイヤの拡大率の変更               */
  708. /*--------------------------------------------------------*/
  709.  
  710. void DMimage_setzoomrate(int rate)
  711. {
  712.     if (zoomrate == rate)
  713.         ;
  714.     else if (zoomrate == 1 && rate > 1)
  715.     {
  716.         zoomrate = rate;
  717.         _dispxlen = 640/zoomrate,  _dispylen = 480/zoomrate;
  718.         vx = dispx - (512-_dispxlen)/2;
  719.         vy = dispy - (256-_dispylen)/2;
  720.         vx = _lim(vx, 0, EIMgetxsize()-512);
  721.         vy = _lim(vy, 0, EIMgetysize()-256);
  722.         scrtype = HIGH16LOW32K;
  723.         setscreen();
  724.         grboxfill(0,0,640,480,0,DrawNORMAL);
  725.         xymemcpy(0x104,0x40000, getds(),(int)EIMadrs(vx,vy),
  726.                  512*2, 256, DMimage_getxbytes(), EIMgetxbytes());
  727.         gwrtpage(1);
  728.         gscrzoom(zoomrate,zoomrate);
  729.         gdsparea(320,240);
  730.         gdsploc(dispx-vx,dispy-vy);
  731.         gwrtpage(0);
  732.         setmenuplt();
  733.         dispalllattice();
  734.     }
  735.     else if (zoomrate > 1 && rate == 1)
  736.     {
  737.         zoomrate = rate;
  738.         _dispxlen = 512, _dispylen = 480;
  739.         dispx = _min(dispx, EIMgetxsize()-512);
  740.         dispy = _min(dispy, EIMgetysize()-256);
  741.         scrtype = HIGH32K;
  742.         setscreen();
  743.         xymemcpy(0x10c,0,
  744.                  getds(),(int)EIMadrs(dispx,dispy),
  745.                  _dispxlen*2, _dispylen,
  746.                  DMimage_getxbytes(), EIMgetxbytes());
  747.         setmenuplt();
  748.         dispalllattice();
  749.     }
  750.     else if (zoomrate > 1 && rate > 1)
  751.     {
  752.         zoomrate = rate;
  753.         _dispxlen = 640/zoomrate,  _dispylen = 480/zoomrate;
  754.         dispx = _min(dispx, EIMgetxsize()-_dispxlen);
  755.         dispy = _min(dispy, EIMgetysize()-_dispylen);
  756.         bool vc = NO;
  757.         if (dispx < vx)
  758.             vx = _max(0, dispx+_dispxlen-512), vc=YES;
  759.         else if (vx+512 < dispx+_dispxlen)
  760.             vx = _min(EIMgetxsize()-512, dispx), vc=YES;
  761.         if (dispy < vy)
  762.             vy = _max(0, dispy+_dispylen-512), vc=YES;
  763.         else if (vy+256 < dispy+_dispylen)
  764.             vy = _min(EIMgetysize()-256, dispy), vc=YES;
  765.         if (vc)
  766.             xymemcpy(0x104,0x40000, getds(),(int)EIMadrs(vx,vy),
  767.                      512*2, 256, DMimage_getxbytes(), EIMgetxbytes());
  768.         gwrtpage(1);
  769.         gdsploc(dispx-vx,dispy-vy);
  770.         gscrzoom(zoomrate,zoomrate);
  771.         gwrtpage(0);
  772.         dispalllattice();
  773.     }
  774. }
  775.  
  776. /*--------------------------------------------------------*/
  777. /*       image レイヤの格子の表示/非表示の切り換え       */
  778. /*--------------------------------------------------------*/
  779.  
  780. void DMimage_setlatticesize(int xlen,int ylen)
  781. {
  782.     erasealllattice();
  783.     lat2xstep = xlen;
  784.     lat2ystep = ylen;
  785.     dispalllattice();
  786. }
  787.  
  788. void DMimage_setlatticeswitch(bool lat1, bool lat2)
  789. {
  790.     erasealllattice();
  791.     _lat1disp = lat1;
  792.     _lat2disp = lat2;
  793.     dispalllattice();
  794. }
  795.  
  796. void DMimage_getlatticeswitch(bool *lat1, bool *lat2)
  797. {
  798.     *lat1 = _lat1disp;
  799.     *lat2 = _lat2disp;
  800. }
  801.  
  802. void DMimage_getlatticesize(int *xsize,int *ysize)
  803. {
  804.     *xsize = lat2xstep;
  805.     *ysize = lat2ystep;
  806. }
  807.  
  808. /*--------------------------------------------------------*/
  809. /*         マスク領域の反転表示スイッチの切り換え         */
  810. /*--------------------------------------------------------*/
  811.  
  812. void DMimage_setmaskdisp(bool disp)
  813. {
  814.     maskdisp = disp;
  815.     DMimage_refresh();
  816. }
  817.  
  818. /*--------------------------------------------------------*/
  819. /*              image レイヤ内での座標を得る              */
  820. /*--------------------------------------------------------*/
  821.  
  822. int DMimage_getx(int x)
  823. // x: menu1レイヤでの座標
  824. {
  825.     return dispx+x/zoomrate;
  826. }
  827.  
  828. int DMimage_gety(int y)
  829. {
  830.     return dispy+y/zoomrate;
  831. }
  832.  
  833. /*--------------------------------------------------------*/
  834. /*            image レイヤに対する描画コマンド            */
  835. /*--------------------------------------------------------*/
  836.  
  837. void DMimage_pset(int x,int y,int col,int op) // imageレイヤに点を打つ
  838. // 点を打つときには、menu1レイヤのbox[0]だけを避ける。
  839. {
  840.     if (scrtype == HIGH16LOW32K)
  841.     {
  842.         x -= vx, y -= vy;
  843.         if (0 <= x && x < 512 && 0 <= y && y < 256)
  844.         {
  845.             if (op == DrawXOR)
  846.                 MEMstoreword_xor(0x104,(char*)(0x40000+1024*y+x*2), col,1);
  847.             else
  848.                 MEMstoreword(0x104,(char*)(0x40000+1024*y+x*2), col,1);
  849.             // gwrtpage(1);
  850.             // gpset(x,y,col,op);
  851.             // gwrtpage(0);
  852.         }
  853.     }
  854.     else if (scrtype == HIGH32K)
  855.     {
  856.         x -= dispx, y -= dispy;
  857.         if (zoomrate == 1)
  858.         {
  859.             Area *ap;
  860.             ap = ALgetfirstarea(menu1box);
  861.             if (0 <= x && x < 512 && 0 <= y && y < 480)
  862.             {
  863.                 if (ap == NULL)
  864.                 {
  865.                     if (op == DrawXOR)
  866.                         MEMstoreword_xor(0x10c,(char*)(1024*y+x*2), col,1);
  867.                     else
  868.                         MEMstoreword(0x10c,(char*)(1024*y+x*2), col,1);
  869.                     // gpset(x,y,col,op);
  870.                 }
  871.                 else if (x < ap->x1 || y < ap->y1 || ap->x2 < x || ap->y2 < y)
  872.                 {
  873.                     if (op == DrawXOR)
  874.                         MEMstoreword_xor(0x10c,(char*)(1024*y+x*2), col,1);
  875.                     else
  876.                         MEMstoreword(0x10c,(char*)(1024*y+x*2), col,1);
  877.                     // gpset(x,y,col,op);
  878.                 }
  879.             }
  880.         }
  881.     }
  882. }
  883.  
  884. void DMimage_line(int x1,int y1,int x2,int y2,int col,int op)
  885. // imageレイヤに直線を描く
  886. {
  887.     int x,y,xr,yr,r;
  888.     xr = _abs(x2-x1), yr = _abs(y2-y1);
  889.     if (xr == 0 && yr == 0)
  890.         DMimage_pset(x1,y1,col,op);
  891.     else if (xr > yr)
  892.     {
  893.         r = (yr<<16) / xr;
  894.         if (x2 < x1)
  895.             { swap(x1,x2); swap(y1,y2); }
  896.         if (y1 > y2)
  897.             r = -r;
  898.         for (x=x1,y=(y1<<16)+0x8000; x<=x2; x++,y+=r)
  899.             DMimage_pset(x,(y>>16),col,op);
  900.     }
  901.     else
  902.     {
  903.         r = (xr << 16) / yr;
  904.         if (y2 < y1)
  905.             { swap(x1,x2); swap(y1,y2); }
  906.         if (x1 > x2)
  907.             r = -r;
  908.         for (y=y1,x=(x1<<16)+0x8000; y<=y2; y++,x+=r)
  909.             DMimage_pset((x>>16),y,col,op);
  910.     }
  911. }
  912.  
  913. void DMimage_hline(int x1,int x2,int y,int col,int op)
  914. // imageレイヤに水平直線を描く
  915. {
  916.     if (scrtype == HIGH16LOW32K)
  917.     {
  918.         gwrtpage(1);
  919.         x1 -= vx, x2 -= vx, y -= vy;
  920.         if (x1>x2)
  921.             swap(x1,x2);
  922.         x1 = _max(0,x1);
  923.         x2 = _min(512-1,x2);
  924.         if (x1 <= x2 && 0<=y && y<256)
  925.             ghline(x1,x2,y,col,op);
  926.         gwrtpage(0);
  927.     }
  928.     else if (scrtype == HIGH32K)
  929.     {
  930.         x1 -= dispx, x2 -= dispx, y -= dispy;
  931.         if (x1>x2)
  932.             swap(x1,x2);
  933.         x1 = _max(0,x1);
  934.         x2 = _min(512-1,x2);
  935.         if (x1 <= x2 && 0<=y && y<480)
  936.         {
  937.             if (zoomrate == 1)
  938.             {
  939.                 bool box = YES;
  940.                 Area *ap = ALgetfirstarea(menu1box);
  941.                 if (ap == NULL)
  942.                     box = NO;
  943.                 else if (y < ap->y1 || ap->y2 < y)
  944.                     box = NO;
  945.                 if (box)
  946.                 {
  947.                     if (x1 < ap->x1)
  948.                         ghline(x1,_min(x2,ap->x1-1),y,col,op);
  949.                     if (ap->x2 < x2)
  950.                         ghline(_max(x1,ap->x2+1),x2,y,col,op);
  951.                 }
  952.                 else
  953.                     ghline(x1,x2,y,col,op);
  954.             }
  955.         }
  956.     }
  957. }
  958.  
  959. void DMimage_hline_map(int x1,int x2,int y,char *colmap)
  960. // colmap には、カラーコードが順に並んでいるものとする。
  961. // この関数は、その色の並びの水平直線を image レイヤに描く。
  962. {
  963.     if (scrtype == HIGH16LOW32K)
  964.     {
  965.         gwrtpage(1);
  966.         x1 -= vx, x2 -= vx, y -= vy;
  967.         if (x1>x2)
  968.             swap(x1,x2);
  969.         int x10 = x1;
  970.         x1 = _max(0,x1);
  971.         x2 = _min(512-1,x2);
  972.         colmap += (x1-x10)*2;
  973.         if (x1 <= x2 && 0<=y && y<256)
  974.         {
  975.             xmemcpy(0x104,0x40000+1024*y+x1*2,getds(),(int)colmap,(x2-x1+1)*2);
  976.             // ghline(x1,x2,y,col,op);
  977.         }
  978.         gwrtpage(0);
  979.     }
  980.     else if (scrtype == HIGH32K)
  981.     {
  982.         x1 -= dispx, x2 -= dispx, y -= dispy;
  983.         if (x1>x2)
  984.             swap(x1,x2);
  985.         int x10 = x1;
  986.         x1 = _max(0,x1);
  987.         x2 = _min(512-1,x2);
  988.         colmap += (x1-x10)*2;
  989.         if (x1 <= x2 && 0<=y && y<480)
  990.         {
  991.             if (zoomrate == 1)
  992.             {
  993.                 bool box = YES;
  994.                 Area *ap = ALgetfirstarea(menu1box);
  995.                 if (ap == NULL)
  996.                     box = NO;
  997.                 else if (y < ap->y1 || ap->y2 < y)
  998.                     box = NO;
  999.                 if (box)
  1000.                 {
  1001.                     if (x1 < ap->x1)
  1002.                     {
  1003.                         int right = _min(x2,ap->x1-1);
  1004.                         xmemcpy(0x10c,1024*y+x1*2,getds(),(int)colmap,(right-x1+1)*2);
  1005.                         // ghline(x1,_min(x2,ap->x1-1),y,col,op);
  1006.                     }
  1007.                     if (ap->x2 < x2)
  1008.                     {
  1009.                         int left = _max(x1,ap->x2+1);
  1010.                         xmemcpy(0x10c,1024*y+left*2,getds(),(int)(colmap+(left-x1)*2),(x2-left+1)*2);
  1011.                         // ghline(_max(x1,ap->x2+1),x2,y,col,op);
  1012.                     }
  1013.                 }
  1014.                 else
  1015.                 {
  1016.                     xmemcpy(0x10c,1024*y+x1*2,getds(),(int)colmap,(x2-x1+1)*2);
  1017.                     // ghline(x1,x2,y,col,op);
  1018.                 }
  1019.             }
  1020.         }
  1021.     }
  1022. }
  1023.  
  1024. void DMimage_vline(int x,int y1,int y2,int col,int op)
  1025. // imageレイヤに垂直直線を描く
  1026. {
  1027.     if (scrtype == HIGH16LOW32K)
  1028.     {
  1029.         gwrtpage(1);
  1030.         x -= vx, y1 -= vy, y2 -= vy;
  1031.         if (y1>y2)
  1032.             swap(y1,y2);
  1033.         y1 = _max(0,y1);
  1034.         y2 = _min(256-1,y2);
  1035.         if (y1 <= y2 && 0<=x && x<512)
  1036.             gvline(x,y1,y2,col,op);
  1037.         gwrtpage(0);
  1038.     }
  1039.     else if (scrtype == HIGH32K)
  1040.     {
  1041.         x -= dispx, y1 -= dispy, y2 -= dispy;
  1042.         if (y1>y2)
  1043.             swap(y1,y2);
  1044.         y1 = _max(0,y1);
  1045.         y2 = _min(480-1,y2);
  1046.         if (y1 <= y2 && 0<=x && x<512)
  1047.         {
  1048.             if (zoomrate == 1)
  1049.             {
  1050.                 bool box = YES;
  1051.                 Area *ap = ALgetfirstarea(menu1box);
  1052.                 if (ap == NULL)
  1053.                     box = NO;
  1054.                 else if (x < ap->x1 || ap->x2 < x)
  1055.                     box = NO;
  1056.                 if (box)
  1057.                 {
  1058.                     if (y1 < ap->y1)
  1059.                         gvline(x,y1,_min(y2,ap->y1-1),col,op);
  1060.                     if (ap->y2 < y2)
  1061.                         gvline(x,_max(y1,ap->y2+1),y2,col,op);
  1062.                 }
  1063.                 else
  1064.                     gvline(x,y1,y2,col,op);
  1065.             }
  1066.         }
  1067.     }
  1068. }
  1069.  
  1070. void DMimage_rboxline(int x,int y,int xlen,int ylen,int col, int op)
  1071. // imageレイヤに矩形(枠)を描く
  1072. {
  1073.     DMimage_hline(x,x+xlen-1,y,col,op);
  1074.     if (ylen >= 2)
  1075.         DMimage_hline(x,x+xlen-1,y+ylen-1,col,op);
  1076.     if (ylen >= 3)
  1077.         DMimage_vline(x,y+1,y+ylen-2,col,op),
  1078.         DMimage_vline(x+xlen-1,y+1,y+ylen-2,col,op);
  1079. }
  1080.  
  1081. void DMimage_boxfill(int x,int y,int xlen,int ylen,int col, int op)
  1082. // imageレイヤに矩形フィルする
  1083. {
  1084.     int iy;
  1085.     for (iy=0; iy<ylen; iy++)
  1086.         DMimage_hline(x,x+xlen-1,y+iy,col,op);
  1087. }
  1088.  
  1089. /*
  1090.     ARTemis の画面表示はすべてこのモジュールを通して行う。
  1091.     32K色高解像度のときと 32K 低解像度のときの画面構成の違いを吸収するため、
  1092.     以下の3つの仮想レイヤを想定し、ARTemis の画面表示はこれらのレイヤに対
  1093.     して行うようプログラミングする。
  1094.  
  1095.         menu1 レイヤ    メニューを表示するためのレイヤ。
  1096.  
  1097.                         このレイヤに対して行える操作は、「矩形領域の設定」
  1098.                         と同じく「解除」の2通りだけである。
  1099.                         矩形領域というのはメニューを表示するための領域で、
  1100.                         「設定」された矩形領域については、他のレイヤを操作
  1101.                         したときにも表示内容をそのままに保つのがDMの働き
  1102.                         である。
  1103.  
  1104.                         このレイヤにアクセスするのは「メニュー管理部」だけで
  1105.                         ある。
  1106.                         メニュー管理部(MM)は、メニューを表示する必要が生じ
  1107.                         た場合、このmenu1レイヤとmenu2レイヤ上に矩形領域を
  1108.                         「借りて」、その領域内でメニュー処理を行う。メニュー
  1109.                         を移動する際には、借りた矩形領域を「返して」別の座標
  1110.                         の領域を借りる、という動作をMMは行う。
  1111.  
  1112.                         DMは「設定された=MMが借りた」領域に対して、そこ
  1113.                         にMMが表示する内容を「守る」はたらきをする。すなわ
  1114.                         ち、imageレイヤにいろいろな操作(スクロールや格子表示
  1115.                         のオン・オフなど)を加えても、menu1レイヤに表示されて
  1116.                         いる内容はそのまま変化せず表示されているようにする。
  1117.  
  1118.         menu2 レイヤ    メニューを表示するためのレイヤその2
  1119.         
  1120.                         menu1 レイヤが32K色高解像度の画面モードのときには、こ
  1121.                         の menu2 レイヤは全くいらない。
  1122.                         しかし、menu1 レイヤが16色モードの場合、menu1 レイヤ
  1123.                         には32K色パレットリストが表示できない。その場合、32K
  1124.                         色パレットリストはこの menu2 レイヤに用意する。
  1125.  
  1126.                         このレイヤは、ハード構成に則して見ると、画面が16色高
  1127.                         解像+32K色低解像度の構成の時に、32K色のページに表示
  1128.                         される。
  1129.                         
  1130.                         この menu2 レイヤに対し行える操作は、「矩形領域の設定」
  1131.                         と同じく「解除」の2通りだけである。
  1132.                         「設定」できる矩形領域は、このレイヤ内に1つだけであ
  1133.                         る。
  1134.                         
  1135.                         このレイヤにアクセスするのはMMだけである。MMは、
  1136.                         画面構成が上のような条件のときにメニューを表示する
  1137.                         必要が生じた場合、menu2 レイヤから矩形領域を「借り
  1138.                         て」そこに、32Kを用いたメニュー表示を行う(もちろん、
  1139.                         メニューが32K色表示を必要としない場合はMMは
  1140.                         menu2 レイヤを使用しない)。
  1141.                         
  1142.                         DMは、image レイヤに対してスクロールや描画などの
  1143.                         操作が行われた場合にも、このmenu2レイヤの表示内容を
  1144.                         画面上で保存する働きをする。
  1145.  
  1146.         image レイヤ    編集画像と格子を表示するためのレイヤ
  1147.  
  1148.                         編集画像を表示する。16色+32K色の2ページ構成の場合
  1149.                         には、32K色ページをハード的に拡大してARTemisの拡大
  1150.                         表示機能を実現する。32K色高解像度の1ページ構成の
  1151.                         場合には、編集画像をソフト的に拡大してARTemisの拡大
  1152.                         表示機能を実現する。
  1153.  
  1154.                         ハード的に見ると、32K色高解像モード×1ページの場合
  1155.                         はそのページのことである。16色高解像+32K色低解像の
  1156.                         場合は、格子を16色高解像のページに表示し、編集画像
  1157.                         を 32K色低解像のページに表示する。
  1158. */
  1159.